﻿#include "widget.h"
#include "ui_widget.h"
#include <QMouseEvent>
#include <QMenu>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
#include <QUrl>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QPainter>
#include <QPixmap>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setFixedSize(368,576);      //设置窗口固定大小
    setWindowFlag(Qt::FramelessWindowHint); //设置无状态栏

    //创建菜单对象
    menu = new QMenu(this);
    menu->addAction(QIcon(":/res/exit.png"),"退出");
    connect(menu,&QMenu::triggered,this,[=]{
        this->close();
    });

    //创建网络管理对象
    manager=new QNetworkAccessManager(this);
    //发送网络请求到该网址
    urlPath="http://t.weather.itboy.net/api/weather/city/101010100";
    QUrl url(urlPath);
    QNetworkRequest request(url);
    reply = manager->get(request);
    //绑定网络请求应答信号
    connect(manager,&QNetworkAccessManager::finished,this,&Widget::readData);

    //06为昨天的标签
    dateList << ui->label_00_date << ui->label_01_date << ui->label_02_date
            << ui->label_03_date << ui->label_04_date << ui->label_05_date
            << ui->label_06_date;
    weekList << ui->label_00_week << ui->label_01_week << ui->label_02_week
            << ui->label_03_week << ui->label_04_week << ui->label_05_week
            << ui->label_06_week;
    iconList << ui->label_00_icon << ui->label_01_icon << ui->label_02_icon
            << ui->label_03_icon << ui->label_04_icon << ui->label_05_icon
            << ui->label_06_icon;
    typeList << ui->label_00_type << ui->label_01_type << ui->label_02_type
            << ui->label_03_type << ui->label_04_type << ui->label_05_type
            << ui->label_06_type;
    airList << ui->label_00_air << ui->label_01_air << ui->label_02_air
            << ui->label_03_air << ui->label_04_air << ui->label_05_air
            << ui->label_06_air;
    fxList << ui->label_00_fx << ui->label_01_fx << ui->label_02_fx
            << ui->label_03_fx << ui->label_04_fx << ui->label_05_fx
            << ui->label_06_fx;
    flList << ui->label_00_fl << ui->label_01_fl << ui->label_02_fl
            << ui->label_03_fl << ui->label_04_fl << ui->label_05_fl
            << ui->label_06_fl;

    //设置图标和对应的路径
    weekIconMap.insert("晴",":/res/weekType/sun.png");
    weekIconMap.insert("多云",":/res/weekType/cloudy.png");
    weekIconMap.insert("阴",":/res/weekType/over.png");
    weekIconMap.insert("阵雨",":/res/weekType/rainstorm.png");
    weekIconMap.insert("雷阵雨",":/res/weekType/thunder.png");
    weekIconMap.insert("多云转晴",":/res/weekType/y_q.png");
    weekIconMap.insert("暴雨",":/res/weekType/rainstorm.png");
    weekIconMap.insert("小雨",":/res/weekType/xiaoyu.png");
    weekIconMap.insert("大雨",":/res/weekType/dayu.png");
    weekIconMap.insert("中雨",":/res/weekType/zhonyu.png");
    weekIconMap.insert("霾",":/res/weekType/霾.png");


    currentIconMap.insert("晴",":/res/type/q.png");
    currentIconMap.insert("多云",":/res/type/qtdy.png");
    currentIconMap.insert("阴",":/res/type/y.png");
    currentIconMap.insert("阵雨",":/res/type/by.png");
    currentIconMap.insert("雷阵雨",":/res/type/lzy.png");
    currentIconMap.insert("多云转晴",":/res/type/qtdy.png");
    currentIconMap.insert("小雨",":/res/type/xy.png");
    currentIconMap.insert("大雨",":/res/type/dayu.png");
    currentIconMap.insert("中雨",":/res/type/zy.png");
    currentIconMap.insert("霾",":/res/type/wm.png");
    //绑定事件过滤器,用于绘制曲线
    ui->widget0405->installEventFilter(this);
    ui->widget0406->installEventFilter(this);

}

Widget::~Widget()
{
    delete ui;
}

//鼠标捕获事件
void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::RightButton)    //事件为鼠标右建
    {
        menu->exec(QCursor::pos());
    }
    if(event->button()==Qt::LeftButton) //点击鼠标左建移动窗口
    {
        //获取鼠标当前位置,event->globalPos();
        //获取当前窗口位置,this->pos();
        //计算偏移值
        mOffset = event->globalPos()-this->pos();
    }
}

//鼠标移动事件，用于移动窗口
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    this->move(event->globalPos() - mOffset);
}

//事件过滤器
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched==ui->widget0405&&event->type()==QEvent::Paint)
    {
        Widget::drawHighLine();
        return true;
    }
    if(watched==ui->widget0406&&event->type()==QEvent::Paint)
    {
        Widget::drawLowLine();
        return true;
    }
    return QWidget::eventFilter(watched,event);
}

//绘制高温曲线
void Widget::drawHighLine()
{
    QPainter painter(ui->widget0405);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setBrush(Qt::yellow);
    painter.setPen(Qt::yellow);
    int avg;
    int sum=0;
    int offSet=0;
    int middle = ui->widget0405->height()/2;
    for(int i=1;i<7;i++)
    {
        sum+=day[i].high.toUInt();
    }
    avg = sum/6;

    //定义6个点
    QPoint points[7];
    for(int i=1;i<7;i++)
    {
        points[i].setX(airList[i]->x()+airList[i]->width()/2);  //x的位置
        offSet = (day[i].high.toInt()-avg);
        points[i].setY(middle-offSet);
        painter.drawEllipse(QPoint(points[i]),3,3);
    }

    painter.drawLine(points[6],points[1]);
    painter.drawText(points[6].x()-5,points[6].y()-5,day[6].high+"°");
    for(int i=1;i<6;i++)
    {
        if(i!=5)
        {
            painter.drawLine(points[i],points[i+1]);
        }
        painter.drawText(points[i].x()-5,points[i].y()-5,day[i].high+"°");
    }


}
//绘制低温曲线
void Widget::drawLowLine()
{
    QPainter painter(ui->widget0406);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setBrush(QColor(58, 160, 255));
    painter.setPen(QColor(58, 160, 255));

    int avg;
    int sum=0;
    int offSet=0;
    int middle = ui->widget0406->height()/2;
    for(int i=1;i<7;i++)
    {
        sum+=day[i].low.toUInt();
    }
    avg = sum/6;

    //定义6个点
    QPoint points[7];
    for(int i=1;i<7;i++)
    {
        points[i].setX(airList[i]->x()+airList[i]->width()/2);  //x的位置
        offSet = (day[i].low.toInt()-avg);
        points[i].setY(middle-offSet);
        painter.drawEllipse(QPoint(points[i]),3,3);
    }

    painter.drawLine(points[6],points[1]);
    painter.drawText(points[6].x()-5,points[6].y()-5,day[6].low+"°");
    for(int i=1;i<6;i++)
    {
        if(i!=5)
        {
            painter.drawLine(points[i],points[i+1]);
        }
        painter.drawText(points[i].x()-5,points[i].y()-5,day[i].low+"°");
    }


}

//设置窗口标签的显示
void Widget::setWeatherData(QByteArray data)
{
    //解析返回的数据
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data);
    if(!jsonDoc.isNull() && jsonDoc.isObject())
    {
        //转换为json对象
        QJsonObject jsonObj = jsonDoc.object();
        //获取城市信息
        if(jsonObj.contains("cityInfo")&&jsonObj["cityInfo"].isObject())
        {
            QJsonObject cityObj = jsonObj["cityInfo"].toObject();
            QString city = cityObj["city"].toString();
            ui->label_02_city->setText(city);
        }

        //获取天气数据
        if(jsonObj.contains("data")&&jsonObj["data"].isObject())
        {
            QJsonObject dataObj = jsonObj["data"].toObject();
            //获取湿度
            QString shidu = dataObj["shidu"].toString();
            //获取pm2.5
            int pm25 = dataObj["pm25"].toInt();
            //获取感冒指数
            QString ganmao = dataObj["ganmao"].toString();
            //获取温度
            QString wendu = dataObj["wendu"].toString()+"℃";
            //获取空气质量
            QString quality = dataObj["quality"].toString();
            if(dataObj.contains("forecast")&&dataObj["forecast"].isArray())
            {
                QJsonArray forecastArray = dataObj["forecast"].toArray();
                for(int i=0;i<6;i++)        //循环5次，依次把每天的数据加入到对应天数的对象中
                {
                    QJsonObject value = forecastArray[i].toObject();
                    if(forecastArray[i].isObject())
                    {
                        day[i].high = value["high"].toString().right(3).left(2);
                        day[i].low = value["low"].toString().right(3).left(2);
                        day[i].ymd = value["ymd"].toString();
                        day[i].week = value["week"].toString();
                        day[i].fx = value["fx"].toString();
                        day[i].fl = value["fl"].toString();
                        day[i].type = value["type"].toString();
                        day[i].notice = value["notice"].toString();
                        day[i].air = value["aqi"].toInt();
                    }
                }
            }
            //获取昨天数据
            if(dataObj.contains("yesterday")&& dataObj["yesterday"].isObject())
            {
                QJsonObject yesterdayObj = dataObj["yesterday"].toObject();
                day[6].high = yesterdayObj["high"].toString().right(3).left(2);
                day[6].low = yesterdayObj["low"].toString().right(3).left(2);
                day[6].ymd = yesterdayObj["ymd"].toString();
                day[6].week = yesterdayObj["week"].toString();
                day[6].fx = yesterdayObj["fx"].toString();
                day[6].fl = yesterdayObj["fl"].toString();
                day[6].type = yesterdayObj["type"].toString();
                day[6].notice = yesterdayObj["notice"].toString();
                day[6].air = yesterdayObj["aqi"].toInt();
            }
            ui->label_wendu->setText(wendu);
            ui->label_ganmao->setText(ganmao);
            ui->label_shidu->setText(shidu);
            ui->label_pm25->setNum(pm25);
            airList[0]->setText(quality);
        }
    }


    //当天的特殊处理
    dateList[0]->setText(day[0].ymd);
    weekList[0]->setText(day[0].week);
    typeList[0]->setText(day[0].type);      //天气类型
    fxList[0]->setText(day[0].fx);
    flList[0]->setText(day[0].fl);
    ui->label_range->setText(QString("%1-%2℃").arg(day[0].low).arg(day[0].high));
    ui->label_notice->setText(day[0].notice);
    //设置当天图标
    QString mapPath = currentIconMap[day[0].type];
    QPixmap pix(mapPath);
    iconList[0]->setPixmap(pix);
    //设置标签
    for(int i=1;i<7;i++)
    {
        //设置星期图标
        QString mapPath = weekIconMap[day[i].type];
        QPixmap pix(mapPath);
        iconList[i]->setPixmap(pix);
        //设置星期信息
        dateList[i]->setText(day[i].ymd.right(5));
        if(i==1)
            weekList[i]->setText("明天");
        else if(i==6)
            weekList[i]->setText("昨天");
        else
            weekList[i]->setText(day[i].week);

        //设置天气类型
        typeList[i]->setText(day[i].type);

        //设置空气质量
        int aqi = day[i].air;
        if(aqi>=0&&aqi<=30)
        {
              airList[i]->setText("优");
              airList[i]->setStyleSheet("border-radius: 7px;"
                                        "background-color: rgb(0, 153, 102);"
                                        "border-top-left-radius: 0px;"
                                        "border-top-right-radius: 0px;");
        }
        else if(aqi>=30&&aqi<=50)
        {
            airList[i]->setText("良");
            airList[i]->setStyleSheet("border-radius: 7px;"
                                      "background-color: rgb(255, 222, 51);"
                                      "border-top-left-radius: 0px;"
                                      "border-top-right-radius: 0px;");
        }
        else if(aqi>=50&&aqi<=70)
        {
            airList[i]->setText("轻度污染");
            airList[i]->setStyleSheet("border-radius: 7px;"
                                      "background-color: rgb(255, 153, 51);"
                                      "border-top-left-radius: 0px;"
                                      "border-top-right-radius: 0px;");
        }
        else if(aqi>=70&&aqi<=100)
        {
            airList[i]->setText("中度污染");
            airList[i]->setStyleSheet("border-radius: 7px;"
                                      "background-color: rgb(204, 0, 51);"
                                      "border-top-left-radius: 0px;"
                                      "border-top-right-radius: 0px;");
        }
        else if(aqi>=100&&aqi<=150)
        {
            airList[i]->setText("严重污染");
            airList[i]->setStyleSheet("border-radius: 7px;"
                                     "background-color: rgb(102, 0, 153);"
                                     "border-top-left-radius: 0px;"
                                     "border-top-right-radius: 0px;");
        }
        else
        {
            airList[i]->setText("重度污染");
            airList[i]->setStyleSheet("border-radius: 7px;"
                                     "background-color: rgb(126, 0, 35);"
                                     "border-top-left-radius: 0px;"
                                     "border-top-right-radius: 0px;");
        }
        fxList[i]->setText(day[i].fx);
        flList[i]->setText(day[i].fl);

    }
    QWidget::repaint(); //刷新图表
}

//用于接收http的回复
void Widget::readData()
{
    //获取返回在状态码
    int retCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    //如果没有错误并且返回码为200，说明访问成功
    if(reply->error()==QNetworkReply::NoError && retCode==200)
    {
        QByteArray data = reply->readAll();
        //该函数将返回的天气信息设置到窗口的相应位置中
        setWeatherData(data);
    }
    else    //访问失败
    {
        //因为主窗口设置了默认的颜色导致字体看不清，设置该窗口的颜色
        QMessageBox mes;
        mes.setWindowTitle("错误");
        mes.setText("网络请求错误");
        mes.setStyleSheet("QPushButton {color:black}");
        mes.setStandardButtons(QMessageBox::Ok);
        mes.exec();
    }
}


//搜索，获取城市名和对应的code，发送http请求
void Widget::on_pushButton_clicked()
{

    urlPath = "http://t.weather.itboy.net/api/weather/city/";

    QString cityName = ui->lineEdit_01_search->text();
    QString cityCode = findCodeFromName.getCityCodeFromName(cityName);
    if(cityCode!=NULL)
    {
        //发送Http请求
        urlPath += cityCode;
        qDebug()<<urlPath;
        reply = manager->get(QNetworkRequest(QUrl(urlPath)));
    }
    else
    {
        QMessageBox mes;
        mes.setWindowTitle("错误");
        mes.setText("城市名输入错误");
        mes.setStyleSheet("QPushButton {color:black}");
        mes.setStandardButtons(QMessageBox::Ok);
        mes.exec();
    }
}
//键盘按下确认按键搜索
void Widget::on_lineEdit_01_search_returnPressed()
{
    on_pushButton_clicked();
}
